/**
 * 本地存储工具
 * 封装微信小程序的本地存储操作，支持对象自动序列化
 */

export const enum StorageKey {
    TOKEN = "token",
    USER_INFO = "user_info",
  // 其他 key...
}

const storage = {
	
	/**
	 * 同步存储缓存
	 * @param {string} key 存储的键名
	 * @param {any} value 存储的值
	 */
	setSync(key: string, value: any): void {
		if (typeof key !== "string") {
			throw new TypeError("Storage key must be a string");
		}
		
		try {
			// 处理特殊类型
			let storageVal = value;
			if (Array.isArray(value) || typeof value === "object") {
				storageVal = JSON.stringify(value);
			}
			uni.setStorageSync(key, storageVal);
		} catch (error) {
			console.error(`Storage set failed for key '${key}': `, error);
			throw new Error("Storage operation failed");
		}
	},
	
	/**
	 * 异步存储缓存
	 * @param {string} key 存储的键名
	 * @param {Promise<any>} value 存储的值
	*/
	set(key: string, value: any): Promise<void> {
		if (typeof key !== "string") {
			throw new TypeError("Storage key must be a string");
		}
		// 处理特殊类型
		let storageVal = value;
		if (Array.isArray(value) || typeof value === "object") {
			storageVal = JSON.stringify(value);
		}
		return new Promise((resolve, reject) => {
			uni.setStorage({
				key,
				data: storageVal,
				success: (res) => {
					resolve();
				},
				fail(error) {
					console.error(`Storage set failed for key '${key}': `, error);
					reject(error);
				}
			})
		})
		
	},
	
	/**
	 * 同步读取缓存
	 * @param {string} key 要获取的键名
	 * @param {any} defaultValue 如果不存在返回的默认值（默认null）
	 * @returns {any} 存储的值或默认值
	*/
	getSync(key: string, defaultValue: any = null): any {
		if (typeof key !== "string") {
			throw new TypeError("Storage key must be a string");
		}
		
		try {

			let value = uni.getStorageSync(key) || defaultValue;
			// 自动解析JSON格式
			try {
				value = JSON.parse(value);
				
			} catch(e) {
				// 不是JSON字符串则保持原样
			}
			return value;
		} catch (error) {
			// 键不存在时返回默认值
			if (typeof error?.message === 'string' && error.message.includes("not found")) {
				return defaultValue;
			}
			console.error(`Storage get failed for key '${key}': `, error);
			return defaultValue;
		}
	},
	
	/**
	 * 异步读取缓存
	 * @param {string} key 要获取的键名
	 * @param {any} defaultValue 如果不存在返回的默认值（默认null）
	 * @returns {Promise<any>} 存储的值或默认值
	*/
	get(key: string, defaultValue: any = null): Promise<any> {
		if (typeof key !== "string") {
			throw new TypeError("Storage key must be a string");
		}
		
		return new Promise((resolve, reject) => {
			uni.getStorage({
				key,
				success(res) {
					let value = res.data || defaultValue;
					// 自动解析JSON格式
					try {
						value = JSON.parse(value);
					} catch(e) {
						// 不是JSON字符串则保持原样
					}
					resolve(value);
				},
				fail(error) {
					if (typeof error?.message === 'string' && error.message.includes("not found")) {
						resolve(defaultValue);
					}
					console.error(`Storage get failed for key '${key}': `, error);
					resolve(defaultValue);
				}
			})
		})
	},
	
	/**
	 * 同步移除指定存储项
	 * @param {string} key 要移除的键名
	 */
	removeSync(key: string): void {
		if (typeof key !== "string") {
			throw new TypeError("Storage key must be a string");
		}
		
		try {
			uni.removeStorageSync(key);
		} catch (error) {
			console.error(`Storage remove failed for key '${key}': `, error);
		}
	},
	
	/**
	 * 同步清空所有存储数据
	 */
	clearSync(): void {
		try {
			uni.clearStorageSync();
		} catch (error) {
			//TODO handle the exception
			console.error("Storage clear failed: ", error);
		}
	},
	
	/**
     * 同步获取存储的所有键名
     * @returns {string[]} 所有存储键的数组
     */
	getAllKeysSync(): string[] {
		try {
			const { keys } = uni.getStorageInfoSync();
			return keys;
		} catch (error) {
			console.error("Get storage keys failed: ", error);
			return [];
		}
	},
	
	/**
	 * 异步获取存储的所有键名
	 * @returns {Promise<string[]>} 所有存储键的数组
	 */
	getAllKeys(): Promise<string[]> {
		return new Promise((resolve, reject) => {
			uni.getStorageInfo({
				success(res) {
					resolve(res.keys);
				},
				fail(error) {
					console.error("Get storage keys failed: ", error);
					resolve([]);
				}
			})
		})
	},
	
	/**
	 * 同步检查键是否存在
	 * @param {string} key 要检查的键名
	 * @returns {boolean} 是否存在
	 */
	hasSync(key: string): boolean {
		try {
            const value = uni.getStorageSync(key);
            return value !== undefined && value !== null;
		} catch (e) {
            console.error(`hasSync error for key: ${key}`, e);
            return false;
		}
	},
	
	/**
	 * 异步检查键是否存在
	 * @param {string} key 要检查的键名
	 * @returns {Promise<boolean>} 是否存在
	 */
	has(key: string): Promise<boolean> {
		return new Promise((resolve, reject) => {
			uni.getStorage({
				key,
				success(res) {
					const value = res.data;
					resolve(value !== undefined && value !== null);
				},
				fail(error) {
					if (typeof error?.message === 'string' && error.message.includes("not found")) {
						resolve(false);
					}
					console.error(`has error for key: ${key}`, error);
					resolve(false);
				}
			})
		})
	},
	
	
}

export default storage;